package org.lc.cmd.connect;

import org.lc.cmd.SubCommand;
import org.lc.cmd.connect.impl.CmdContextSetter;
import org.lc.cmd.exp.DevException;
import org.lc.cmd.model.RequestFinishData;

public interface RequestHandler {
    default void handle(ServerContext context) {
        try {
            setCmdContext(context);
            Object result;
            try {
                SubCommand command = matchCommand((ServerRequest) context.request());
                result = invoke(command, context);
            } catch (Exception e) {
                // 命令抛出异常也认为是执行结果
                result = e;
            }
            RequestFinishData requestFinishData = convertResult(context, result);
            clearCmdContext();
            handleFinish(requestFinishData);
        } catch (Exception e) {
            // 除了内部try的部分，其余方法不允许出现异常
            throw new DevException(e);
        }
    }

    SubCommand matchCommand(ServerRequest request);

    Object invoke(SubCommand command, ServerContext context);

    RequestFinishData convertResult(ServerContext context, Object result);

    void handleFinish(RequestFinishData requestFinishData);

    default void setCmdContext(ServerContext context) {
        CmdContextSetter contextSetter =
                CmdServerConfig.defaultProvider.contextSupplier().get().getBean(CmdContextSetter.class);
        contextSetter.setCurrentContext(context);
    }

    default void clearCmdContext() {
        CmdContextSetter contextSetter =
                CmdServerConfig.defaultProvider.contextSupplier().get().getBean(CmdContextSetter.class);
        contextSetter.clearCurrentContext();
    }
}
